home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
proport.zip
/
PROPORT.A86
< prev
next >
Wrap
Text File
|
1989-08-05
|
19KB
|
930 lines
; PROPORT Editor port program for PROCOMM. Supports aliases, etc.
; Usage: proport (no arguments)
; Prompt the user for a DOS command, and execute it.
; proport >file
; List the aliases to that file.
; proport <file
; Load the aliases from that file. The program
; PROPORT.COM should have been run from the current
; directory, and should not be write protected.
; Aliases are of the form xx=yyy zz, one per line. A comment line may
; begin with a semicolon. Leading spaces are also ignored. If the first
; part of the command line matches the alias, then the part to the right
; is substituted. If the command line begins with an `at' symbol (`@'),
; or if the called program terminates with an error condition, then
; PROPORT will issue a `wolf-whistle' (courtesy of SDF.COM).
; This program supports pipes, redirection, and internal and external
; commands. It calls internal commands by calling COMMAND.COM with the /C
; switch and calls external commands directly, so that their exit codes
; can be returned. (COMMAND.COM does not return exit codes, so internal
; commands will never return an exit code.)
; Much of this code is already present in some form in COMMAND.COM; it
; would have been much easier if this had been available as a subfunction
; of the EXEC call. Ahem. :-( .
; Assemble with A86.
TAB equ 9
LF equ 10
CR equ 13
CPMEOF equ 26
; Addresses in high memory.
envseg equ 2ch ;segment of environment
fcb1 equ 5ch ;first FCB to put in new process
fcb2 equ 6ch ;second ...
strs equ 85h ;start+5 of area to store various strings
jmp start ;jump to start of code
db 0,0 ;five padding bytes
; Data area.
block dw 0,0,0,fcb1,0,fcb2,0 ;parameter block for EXEC call
pipe1 db '_:/%PIPE1.$$$',0
zero equ pipe1+13
pipe2 db '_:/%PIPE2.$$$',0
intcmds db 'BREAK',0,'CD',0,'CHDIR',0,'CLS',0,'COPY',0,'CTTY',0,'DATE',0
db 'DEL',0,'DIR',0,'ECHO',0,'ERASE',0,'EXIT',0,'FOR',0,'GOTO',0
db 'IF',0,'MD',0,'MKDIR',0,'PATH',0,'PAUSE',0,'PROMPT',0,'RD',0
db 'REM',0,'REN',0,'RENAME',0,'RMDIR',0,'SET',0,'SHIFT',0,'TIME',0
db 'TYPE',0,'VER',0,'VERIFY',0,'VOL',0,0
dosver db 0 ;DOS version
swchar db 0 ;switch character (usually '/')
innam dw 0 ;address of string of '<' file
pipnam dw 0 ;address of string of pipe file
outnam dw 0 ;address of string of '>' file
appflg db 0 ;nonzero if '>>' was used
delflg db 0 ;nonzero if input file is to be deleted
inhndl db -1 ;internal handle for orig. stdin
outhndl db -1 ;internal handle for orig. stdout
next dw 0 ;next pipe to process
bgnpath dw 0 ;address of first char. of path name
bgnfil dw 0 ;addr of first char. of filename proper
endfil dw 0 ;addr of last char. of filename proper
envpos dw 0 ;current position in path string in environment
pathaddr dw 0 ;address of PATH environment variable
cmdaddr dw 0 ;address of COMSPEC variable
whflag db 0 ;nonzero for whistle
whtime dw 100 ;timing constant (default 100 if patched)
; Begin permanent part of code.
sy10: mov sp,offset end1+200
int 21h ;shrink used memory
; Begin execution loop.
; At this point si = address of next command.
sy11: mov di,si ;find end of current string
mov al,0
mov cx,-1
repnz scasb
mov dx,innam
or dx,dx
jz sy12 ;if no input file given
; Open input file.
mov ax,3d00h ;open for reading
int 21h
jc sy12a ;if error
xchg ax,bx
mov al,-1 ;force it into handle 0
xchg al,[bx+18h]
xchg al,[18h]
mov inhndl,al
; Open output or pipe file.
sy12: cmp byte [di],0
jne sy13 ;if we are piping
mov dx,outnam
mov pipnam,dx
or dx,dx
jz sy18 ;if no output redirection
cmp byte appflg,0
jz sy15 ;if no appending
mov ax,3d01h ;open for writing
int 21h
jc sy12a
xchg ax,bx
mov ax,4202h ;LSEEK
xor cx,cx
xor dx,dx
int 21h
jmp short sy17
sy12a: mov dx,offset msg1 ;error opening I/O redirection file
jmp err
; Open pipe file.
sy13: mov dx,offset pipe1
cmp dx,innam
jne sy14 ;if not duplicate
mov dx,offset pipe2
sy14: mov pipnam,dx
cmp byte dosver,2
je sy15 ;if DOS 2
mov ah,5ah ;create unique file
mov bx,dx
mov byte [bx+3],0
jmp short sy16
sy15: mov ah,3ch ;create file
sy16: xor cx,cx ;attribute
int 21h
xchg ax,bx
jnc sy17 ;if no error
mov dx,offset msg2 ;cannot open pipe
errj1: jmp err
sy17: mov al,-1 ;move it to handle #1
xchg al,[bx+18h]
xchg al,[19h]
mov outhndl,al
sy18: mov next,di
; Process the input line. At this point si points to the beginning of the
; current line and di to the next.
; Check for: 1. Drive change.
; 2. Internal command.
; 3. External command with explicit drive or path.
; 4. External command.
push si
mov dl,swchar
mov ax,2900h ;parse filename
mov di,fcb1
int 21h
or al,al
mov dx,offset msg3 ;invalid drive
js errj1
mov dx,offset msg4 ;bad command or file name
jnz errj1
cmp byte [di],0
je sy19 ;if no drive given
cmp byte [di+1],' '
jne sy24 ;if part of filename given
mov al,[si]
call ifslash
je sy24 ;if slash, then part of a filename is here
; Change current drive.
mov ah,0eh ;select disk
mov dl,[di]
dec dx
int 21h
jmp done ;done
; Check for internal command.
sy19: mov al,[si]
call ifslash
jne sy20 ;if not a slash, then this is not option 3.
inc byte [di]
sy20: mov di,offset intcmds
mov al,0
sy21: cmp al,[di]
je sy24 ;if end of list
mov cx,8
mov si,fcb1+1
repe cmpsb
dec di
cmp byte [si-1],' '
jne sy22 ;if unequal
scasb
je sy23 ;if [di]=0, then they match
sy22: repnz scasb ;skip to next string
jmp sy21
; Process internal command.
sy23: pop si
sub si,4
mov di,si
mov al,' ' ;prepend " /C "
mov ah,swchar
stosw
mov ax,' C'
stosw
call do80h
mov ax,4b00h ;EXEC
mov dx,cmdaddr
mov ds,[envseg]
mov bx,offset block
int 21h
cld
mov bx,cs
mov ss,bx
mov sp,offset end1+200
mov ds,bx
mov es,bx
mov dx,offset msg5 ;cannot load COMMAND.COM
if c jmp err
donej1: jmp done
; Process external command. At this point, the start address of the
; string is on top of the stack, and the first byte of FCB1 is zero if
; paths are to be searched.
sy24: mov di,offset zero
cmp byte [fcb1],0
jnz sy25 ;if drive or path given
mov di,pathaddr
sy25: pop si ;start of string
mov envpos,di ;save environment position
call len2sep
mov di,offset end1+80
sub di,cx
mov bgnfil,di ;beginning of file name
mov bgnpath,di
rep movsb ;move filename over
mov endfil,di ;end of file name
; Set up FCB's & parameter string.
push si
call swskip ;skip switches
mov ax,2901h ;parse filename
mov di,fcb1
int 21h
sy26: lodsb ;skip till separator
cmp al,dl
je sy27 ;if switchar
cmp al,0
je sy27 ;if end
call ifsep
jne sy26 ;if not separator
sy27: dec si
call swskip
mov ax,2901h ;parse filename
mov di,fcb2
int 21h
pop si ;back to start of string
call do80h ;do parameter string
; Loop over paths. At this point, the path is prepended to the file name
; and bgnpath is set accordingly. ds=es=ss=cs.
sy28: mov di,endfil ;add .COM
mov ax,'C.'
stosw
mov ax,'MO'
stosw
mov al,0
stosb
sy29: mov ax,4b00h ;EXEC
mov bx,offset block
mov dx,bgnpath
int 21h
cld
mov bx,cs
mov ss,bx
mov sp,offset end1+200
mov ds,bx
mov es,bx
jnc donej1 ;if done
cmp ax,2
jne err0 ;if error other than file not found
and sp,-2
mov di,endfil
inc di
cmp byte [di],'C'
jne sy30 ;if we just did .EXE
mov ax,'XE'
stosw
stosb
jmp sy29 ;go back and try .EXE
; Try another path.
sy30: mov si,envpos ;environment position
mov ds,[envseg]
call skipsep
cmp al,0
mov dx,offset msg4 ;bad command or file name
je err ;if no more paths
mov cx,si ;get length of next path
sy31: lodsb
cmp al,0
je sy32 ;if end of string
call ifsep
jne sy31 ;if not separator
sy32: dec si
mov cs:envpos,si
sy33: dec si
cmp byte [si],'/'
je sy33 ;skip trailing slashes
cmp byte [si],'\'
je sy33 ;skip trailing slashes
inc si
xchg cx,si
sub cx,si ;cx = length
mov di,cs:bgnf